/******************************************************************************************************
    1、北斗协议和GPS协议不一样，不是以"\r\n"为一条协议的结束.
    2、printf函数中的打印信息是const字符串常量，放在cpu内部flash，北斗模块printf打印过多，导致scanf("%s",payload);输入的内容被改写.
    3、协议发送时不要使用结构体表示发送内容，接收时可以使用结构体表示接收内容.
    4、调试协议时使用串口监视工具AccessPort进行串口协议抓包.
    5、Msp430F5438:RAM(16KB),内部flash(256KB + 256B),4个串口.
    6、注意北斗协议净荷封装的是RTU的协议，由于RTU协议也是以'$'符号位为协议的开始，因此需要进行转义，本程序以'M'替代净荷中的'$'.
    7、Created by xumin,2015-05-20,copyright is reserved.
******************************************************************************************************/
 
// #include "..\..\include\includes.h"
 
#ifdef DEF_COMPILE_PROJECT_APP
 
#ifdef BD_COMM_SUPPORT
 
unsigned char bd_buf_bitmap = 0;
 
//unsigned char dwxx_buf[todo];
unsigned char txxx_buf[TXXX_MAX_SIZE];
unsigned char icxx_buf[ICXX_FIRM_SIZE];
unsigned char zjxx_buf[ZJXX_FIRM_SIZE];
//unsigned char sjxx_buf[todo];
//unsigned char bbxx_buf[todo];
unsigned char fkxx_buf[FKXX_FIRM_SIZE];
 
unsigned int rx_packet_len = 0;
unsigned char bd_rx_char;
unsigned int bd_buf_pointer = 0;
unsigned char bd_shared_rx_buf[RX_BD_MAX_DATA_SIZE];
 
unsigned char  g_src_user_addr[3];
unsigned char  g_dst_user_addr[3];
unsigned char g_transfer_format;
 
 
void init_uart3_for_bd()
{
#if 1 //波特率115200配置
    P10SEL |= BIT4 + BIT5;
    
    UCA3CTL1 |= UCSWRST; //USCI状态机复位
    
    UCA3CTL1 |= UCSSEL_2;  //SMCLK 
    
    UCA3BR0 = 69; //115200
    UCA3BR1 = 0x00;
    UCA3MCTL = 0x06; //波特率微调
    
    UCA3CTL1 &= ~UCSWRST; //初始化USCI状态机
    
    UCA3IE |=  UCRXIE; //使能BD串口RX中断
   
#else  //波特率9600配置
    P10SEL |= BIT4+BIT5;
 
    UCA3CTL1 |= UCSWRST;//USCI状态机复位
    
    UCA3CTL1 |= UCSSEL_1;//ACLK
                  
    UCA3BR0 = 0x03;//9600
    UCA3BR1 = 0x00; 
    UCA3MCTL = 0x06;//波特率微调
 
    UCA3CTL1 &= ~UCSWRST;//初始化USCI状态机
 
    UCA3IE |=  UCRXIE;  //使能BD串口RX中断
#endif
}
 
/* 
    异或校验和算法 
 */
 static unsigned char xor_checksum (unsigned char *buf, unsigned int len)
{
    unsigned int i;
    unsigned char checksum = 0;
 
    for (i = 0; i < len; ++i)
    {
        checksum ^= *(buf++);
    }
 
    return checksum;
}
 
void tx_uart3_char(unsigned char c)
{
    while (!(UCA3IFG & UCTXIFG));
    
    UCA3TXBUF  = c;
}
 
void tx_uart3_string(unsigned char *str, unsigned int len)
{
    unsigned int i;  
    
    for (i = 0 ; i < len; ++i)
    {
        tx_uart3_char(*(str + i));
    }
}
 
void create_txsq(unsigned char *src_user_addr, unsigned char *dst_user_addr, 
                                unsigned char transfer_format, unsigned char *payload, 
                                unsigned int payload_len, unsigned char *send_txsq_data)
{    
    /* 1、通信申请指令初始化，不采用memcpy等库函数，提高指令执行效率,只有涉及到大量数据赋值拷贝时才考虑用库函数 */
    send_txsq_data[0] = '$';   
    send_txsq_data[1] = 'T';   
    send_txsq_data[2] = 'X';  
    send_txsq_data[3] = 'S';  
    send_txsq_data[4] = 'Q';  
 
    /* 2、包长度，先传高位，再传低位 */
    send_txsq_data[5] = (TXSQ_FIRM_SIZE +  payload_len) / 256;
    send_txsq_data[6] = (TXSQ_FIRM_SIZE +  payload_len) % 256;
 
    /* 3、源用户地址 */
    send_txsq_data[7] = *src_user_addr;
    send_txsq_data[8] = *(src_user_addr + 1);
    send_txsq_data[9] = *(src_user_addr + 2);
    
    /* 4.1、信息-信息类别 */
    if (transfer_format == 0) //汉字
    {
        send_txsq_data[10] = TXSQ_PAYLOAD_CHINESE;//0b01000100; 
    }
    else //代码/混发
    {
        send_txsq_data[10] = TXSQ_PAYLOAD_BCD;//0b01000110;
    }
 
    /* 4.2、信息-目的用户地址 */
    send_txsq_data[11] = *dst_user_addr;
    send_txsq_data[12] = *(dst_user_addr + 1);
    send_txsq_data[13] = *(dst_user_addr + 2);
 
    /* 4.3、信息-电文净荷长度-单位是bit */ 
     send_txsq_data[14] = (payload_len * 8) / 256;
     send_txsq_data[15]  = (payload_len * 8) % 256;  
 
    /* 4.4、信息-是否应答 */
     send_txsq_data[16]  = 0;
 
    /* 4.5、信息-电文内容 */
    memcpy(&send_txsq_data[17] , payload, payload_len);
 
    /* 5、校验和 */
    send_txsq_data[TXSQ_FIRM_SIZE + payload_len -1] = xor_checksum(send_txsq_data, (TXSQ_FIRM_SIZE +  payload_len -1));
    printf("\r\n    xor_checksum = 0x%x\r\n",  xor_checksum(send_txsq_data, (TXSQ_FIRM_SIZE +  payload_len -1)));
}
 
void send_dwsq()
{
    //todo
}
 
/* 
    1、结构体不宜管理可变长度的数据协议,如通讯申请协议
    2、发送长度为6个字节("我爱你")，发送方式为中文，协议内容:
       txsq:24 54 58 53 51 00 18 02 ad f7 44 02 ad f7 00 30 00 ce d2 b0 ae c4 e3 63
       txxx:24 54 58 58 58 00 1a 02 ad f7 40 02 ad f7 00 00 00 30 ce d2 b0 ae c4 e3 00 67
 */
void send_txsq(unsigned char cmd, unsigned char *src_user_addr, unsigned char *dst_user_addr, 
                             unsigned char transfer_format, unsigned char *send_txsq_payload, unsigned int send_txsq_payload_len)
{
    unsigned int i;
    unsigned char l_transfer_format;
    unsigned int payload_len;
    unsigned long src_user_addr_long;
    unsigned long dst_user_addr_long;
    unsigned char l_src_user_addr[3];
    unsigned char l_dst_user_addr[3];
    unsigned char payload[MAX_PAYLOAD_LEN];
    unsigned char send_txsq_data[TXSQ_FIRM_SIZE + MAX_PAYLOAD_LEN]; 
 
    if (cmd == 1)
    {
        UCA2IE &=  ~UCRXIE; 
 
        DebugPrintBd("\r\n    输入十六进制用户地址(如02adf7,02adfb):");
        scanf("%lx", &src_user_addr_long);  
 
        DebugPrintBd("\r\n    输入十六进制目的用户地址(如02adf7,02adfb):");
        scanf("%lx", &dst_user_addr_long);
 
        DebugPrintBd("\r\n    内容编码(0:汉字,1代码):");
        scanf("%d",&l_transfer_format);
 
#if 1      
        DebugPrintBd("\r\n    发送内容:");
        scanf("%s", payload);
        payload_len = strlen((char const *)payload);
#else
        DebugPrintBd("\r\n    输入发送内容长度:");
        scanf("%d", &payload_len);
        //payload_len = 78;
        for (i = 0; i < payload_len; ++i)
        {
            payload[i] = 0x5a;
        }
#endif
 
        UCA2IE |=  UCRXIE; 
         
        l_src_user_addr[0] = src_user_addr_long / 65536;
        l_src_user_addr[1] = (src_user_addr_long % 65536) / 256;
        l_src_user_addr[2] = (src_user_addr_long % 65536) % 256;
        
        l_dst_user_addr[0] = dst_user_addr_long / 65536;
        l_dst_user_addr[1] = (dst_user_addr_long % 65536) / 256;
        l_dst_user_addr[2] = (dst_user_addr_long % 65536) % 256;       
 
        for (i = 0; i < 3; ++i)
        {
            g_src_user_addr[i] = l_src_user_addr[i];
            g_dst_user_addr[i] = l_src_user_addr[i];
        }
        
        g_transfer_format = l_transfer_format;      
  
        
        create_txsq(l_src_user_addr, l_dst_user_addr, l_transfer_format, payload, payload_len, send_txsq_data);
        tx_uart3_string(send_txsq_data, (TXSQ_FIRM_SIZE + payload_len));
    }
    else
    {
        create_txsq(src_user_addr, dst_user_addr, transfer_format, send_txsq_payload, send_txsq_payload_len, send_txsq_data);
        tx_uart3_string(send_txsq_data, (TXSQ_FIRM_SIZE + send_txsq_payload_len));
    }
    
}
 
void send_cksc()
{
    //todo
}
 
/*  
    1、IC检测协议内容:
       icjc:24 49 43 4A 43 00 0C 00 00 00 00 2B 	
       icxx:24 49 43 58 58 00 16 02 AD F7 00 00 00 0B 06 00 3C 03 00 00 00 52 
 */
void send_icjc()
{
    unsigned char send_icjc_data[XTZJ_FIRM_SIZE];
    
    send_icjc_data[0] = '$';  
    send_icjc_data[1] = 'I';
    send_icjc_data[2] = 'C'; 
    send_icjc_data[3] = 'J';
    send_icjc_data[4] = 'C';
    
    send_icjc_data[5] = ICJC_FIRM_SIZE / 256;  //先传高位
    send_icjc_data[6] = ICJC_FIRM_SIZE % 256; //再传低位
    
    send_icjc_data[7] = 0x00;
    send_icjc_data[8] = 0x00;
    send_icjc_data[9] = 0x00;
 
    send_icjc_data[10] = 0x00;
 
    send_icjc_data[11] = xor_checksum(send_icjc_data, (XTZJ_FIRM_SIZE - 1)); 
 
    tx_uart3_string(send_icjc_data, XTZJ_FIRM_SIZE); 
}
 
/*  
    1、XTZJ协议内容:
       xtzj:24  58 54 5A 4A 00 0D 02 AD FB 00 00 61 	
       zjxx:24 5a 4a 58 58 00 15 02 AD FB 01 00 64 02 00 00 03 00 02 00 13 
 */
 
void send_xtzj()
{
    unsigned long user_addr;
    unsigned int frequency;
    unsigned char send_xtzj_data[XTZJ_FIRM_SIZE];
 
    UCA2IE &=  ~UCRXIE;    
 
    DebugPrintBd("\r\n    输入十六进制用户地址(如02adf7):");
    scanf("%lx", &user_addr);
 
    DebugPrintBd("\r\n    输入系统自检的频度:");
    scanf("%d", &frequency);
 
    UCA2IE |=  UCRXIE; 
 
    send_xtzj_data[0] = '$';
    send_xtzj_data[1] = 'X';
    send_xtzj_data[2] = 'T';
    send_xtzj_data[3] = 'Z';
    send_xtzj_data[4] = 'J';
 
    send_xtzj_data[5] = XTZJ_FIRM_SIZE / 256; //先传高位
    send_xtzj_data[6] = XTZJ_FIRM_SIZE % 256; //再传低位
 
    send_xtzj_data[7] = user_addr / 65536;
    send_xtzj_data[8] = (user_addr % 65536) / 256;
    send_xtzj_data[9] = (user_addr % 65536) % 256;
 
    send_xtzj_data[10] = frequency / 256;
    send_xtzj_data[11] = frequency % 256;
 
    send_xtzj_data[12] = xor_checksum(send_xtzj_data, XTZJ_FIRM_SIZE-1);
    
    tx_uart3_string(send_xtzj_data, XTZJ_FIRM_SIZE);
}
 
void send_sjsc()
{
    //todo
}
 
void send_bbdq()
{
    //todo
}
 
void parse_txxx(struct txxx_struct *txxx)
{
    unsigned int i;
    unsigned int payload_len;
    unsigned char send_data[104];//用途有2
 
    /* 1、指令内容 */
    for (i = 0; i < 5; ++i)
    {
        (*txxx).instruction[i] = txxx_buf[i];
    }
 
    /* 2、接收包长 */
    (*txxx).packet_len = txxx_buf[5] * 256 + txxx_buf[6];
 
    /* 3、目的用户地址 */
    for (i = 0; i < 3; ++i)
    {
        (*txxx).user_addr[i] = txxx_buf[i + 7];
    }
 
    /* 4.1、信息-信息类别 */
    memcpy(&((*txxx).txxx_info.txxx_info_type), (txxx_buf + 10), 1);   
 
    /* 4.2、信息-发送方地址 */
    for (i = 0; i < 3; ++i)
    {
        (*txxx).txxx_info.src_user_addr[i] = txxx_buf[i + 11];
    }
    
    /* 4.3、信息-发送时间 */
    (*txxx).txxx_info.send_time.hour = txxx_buf[14];
    (*txxx).txxx_info.send_time.minute = txxx_buf[15];
        
    /* 4.4、信息-电文长度 */
    (*txxx).txxx_info.payload_len = txxx_buf[16] * 256 + txxx_buf[17];
    payload_len = (*txxx).txxx_info.payload_len / 8;
    
    /* 4.5、信息-电文内容 */
    memcpy((*txxx).txxx_info.payload, (txxx_buf + 18), payload_len);
 
    /* 4.6、信息-CRC */
    (*txxx).txxx_info.crc = txxx_buf[18 + payload_len];
 
    /* 5、校验和 */
    (*txxx).checksum = txxx_buf[18 + payload_len + 1];
 
    if ((txxx_buf[18] == 'z') && (txxx_buf[19] == 't')/* (txxx_buf[18] == 'z') && (txxx_buf[19] == 't') && (txxx_buf[20] == 'c') && (txxx_buf[20] == 'x') */)
    {
#if 1
        create_send_data_1(send_data);
        send_txsq(0, &(*txxx).user_addr[0], &(*txxx).txxx_info.src_user_addr[0], g_transfer_format, send_data, (104-37));
#else   
        for (i = 0; i < (104-37); ++i)
        {
            send_data[i] = 0x5a;
        }
    
        send_data[0] = 'M';
        send_data[1] = (104-37);
        send_txsq(0, &(*txxx).user_addr[0], &(*txxx).txxx_info.src_user_addr[0], g_transfer_format, send_data, (104-37));
#endif      
       
    }else if ( (txxx_buf[18] == 'M') && (txxx_buf[19] == (104-37)) )
    {
        create_send_data_2(send_data, &txxx_buf[18], payload_len);
        SendData(104, 1, GSMNEW_ENUM_measureCurSend, send_data); 
    } 
}
 
void parse_icxx(struct icxx_struct *icxx)
{
    unsigned int i;
 
    for (i = 0; i < 5; ++i)
    {
        (*icxx).instruction[i] = icxx_buf[i];
    }
 
    (*icxx).packet_len = icxx_buf[5] * 256 + icxx_buf[6];
 
    for (i = 0; i < 3; ++i)
    {
        (*icxx).user_addr[i] = icxx_buf[i + 7];
    }
 
    (*icxx).icxx_info.frame_id = icxx_buf[10];
 
    for (i = 0; i < 3; ++i)
    {
        (*icxx).icxx_info.broadcast_id[i] = icxx_buf[i + 11];
    }
 
    (*icxx).icxx_info.user_feature = icxx_buf[14];
 
    (*icxx).icxx_info.service_frequency = icxx_buf[15] * 256 + icxx_buf[16];
 
    (*icxx).icxx_info.comm_level = icxx_buf[17];
 
    (*icxx).icxx_info.encryption_flag = icxx_buf[18];
 
    (*icxx).icxx_info.user_num = icxx_buf[19] * 256 + icxx_buf[20];
 
    (*icxx).checksum = icxx_buf[21];
    
}
 
void parse_zjxx(struct zjxx_struct *zjxx)
{
    unsigned int i;
 
    for (i = 0; i < 5; ++i)
    {
        (*zjxx).instruction[i] = zjxx_buf[i];
    }
 
    (*zjxx).packet_len = zjxx_buf[5] * 256 + zjxx_buf[6];
 
    for (i = 0; i < 3; ++i)
    {
        (*zjxx).user_addr[i] = zjxx_buf[i + 7];
    }
 
    (*zjxx).zjxx_info.ic_status = zjxx_buf[10];
 
    (*zjxx).zjxx_info.hw_status = zjxx_buf[11];
 
    (*zjxx).zjxx_info.battery_quantity = zjxx_buf[12];
 
    (*zjxx).zjxx_info.in_station_status = zjxx_buf[13];
 
    for (i = 0; i < 6; ++i)
    {
        (*zjxx).zjxx_info.power_status[i] = zjxx_buf[14 + i];
    }
 
    (*zjxx).checksum = zjxx_buf[20];
}
 
void parse_fkxx(struct fkxx_struct *fkxx)
{
    unsigned int i;
 
    for (i = 0; i < 5; ++i)
    {
        (*fkxx).instruction[i] = fkxx_buf[i];
    }
 
    (*fkxx).packet_len = fkxx_buf[5] * 256 + fkxx_buf[6];
    
    for (i = 0; i < 3; ++i)
    {
        (*fkxx).user_addr[i] = fkxx_buf[i + 7];
    }
 
    (*fkxx).fkxx_info.fk_flag = fkxx_buf[10];
 
    for (i = 0; i < 4; ++i)
    {
        (*fkxx).fkxx_info.extra_info[i] = fkxx_buf[11 + i];
    }
 
    (*fkxx).checksum = fkxx_buf[15];
}
 
void print_txxx(struct txxx_struct *txxx)
{
    unsigned int i;
    
    Tx_monitor_S("\r\n    ========= TXXX包-打印开始=========\r\n");
 
    DebugPrintBd("\r\n    TXXX包总长度:%d", (*txxx).packet_len);
    DebugPrintBd("\r\n    TXXX包用户地址:0x%02x%02x%02x", (*txxx).user_addr[0], (*txxx).user_addr[1], (*txxx).user_addr[2]);
    DebugPrintBd("\r\n    TXXX包信息内容-发送方地址:0x%02x%02x%02x", (*txxx).txxx_info.src_user_addr[0], (*txxx).txxx_info.src_user_addr[1], (*txxx).txxx_info.src_user_addr[2]);
    DebugPrintBd("\r\n    TXXX包信息内容-发送时间:%02d时%02d分",  (*txxx).txxx_info.send_time.hour,  (*txxx).txxx_info.send_time.minute);
    DebugPrintBd("\r\n    TXXX包信息内容-电文长度:%d字节", (*txxx).txxx_info.payload_len / 8);
    DebugPrintBd("\r\n    TXXX包信息内容-电文内容:");
    for (i = 0; i < ((*txxx).txxx_info.payload_len / 8); ++i)
    {
        DebugPrintBd("%02x ", (*txxx).txxx_info.payload[i]);
    }
    DebugPrintBd("\r\n    TXXX包信息内容-CRC:0x%02x", (*txxx).txxx_info.crc);
    DebugPrintBd("\r\n    TXXX包校验和:0x%02x", (*txxx).checksum);
    
    DebugPrintBd("\r\n    ========= TXXX包-打印结束=========\r\n");
}
 
void print_icxx(struct icxx_struct *icxx)
{
    Tx_monitor_S("\r\n    ========= ICXX包-打印开始=========\r\n");
    
    DebugPrintBd("\r\n    ICXX包总长度:%d", (*icxx).packet_len);
    DebugPrintBd("\r\n    ICXX包用户地址:0x%02x%02x%02x", (*icxx).user_addr[0], (*icxx).user_addr[1], (*icxx).user_addr[2]);   
    DebugPrintBd("\r\n    ICXX信息内容-帧号:%d", (*icxx).icxx_info.frame_id);   
    DebugPrintBd("\r\n    ICXX信息内容-通播ID:0x%02x%02x%02x", (*icxx).icxx_info.broadcast_id[0], (*icxx).icxx_info.broadcast_id[1], (*icxx).icxx_info.broadcast_id[2]);
    DebugPrintBd("\r\n    ICXX信息内容-用户特征:%d", (*icxx).icxx_info.user_feature);      
    DebugPrintBd("\r\n    ICXX信息内容-服务频度:%d秒", (*icxx).icxx_info.service_frequency);   
    DebugPrintBd("\r\n    ICXX信息内容-通信级别:%d", (*icxx).icxx_info.comm_level);   
    DebugPrintBd("\r\n    ICXX信息内容-加密标志:%d", (*icxx).icxx_info.encryption_flag);   
    DebugPrintBd("\r\n    ICXX信息内容-用户数目:%d", (*icxx).icxx_info.user_num);   
    DebugPrintBd("\r\n    ICXX包校验和:0x%02x\r\n", (*icxx).checksum);
    
    DebugPrintBd("\r\n    ========= ICXX包-打印结束=========\r\n");
}
 
void print_zjxx(struct zjxx_struct *zjxx)
{
    Tx_monitor_S("\r\n    ========= ZJXX包-打印开始=========\r\n");
    
    DebugPrintBd("\r\n    ZJXX包总长度:%d", (*zjxx).packet_len);
    DebugPrintBd("\r\n    ZJXX包用户地址:0x%02x%02x%02x", (*zjxx).user_addr[0], (*zjxx).user_addr[1], (*zjxx).user_addr[2]);   
    DebugPrintBd("\r\n    ZJXX信息内容-IC卡状态:0x%02x", (*zjxx).zjxx_info.ic_status);      
    DebugPrintBd("\r\n    ZJXX信息内容-硬件状态:0x%02x", (*zjxx).zjxx_info.hw_status);   
    DebugPrintBd("\r\n    ZJXX信息内容-电池电量:0x%02x", (*zjxx).zjxx_info.battery_quantity);   
    DebugPrintBd("\r\n    ZJXX信息内容-入站状态:0x%02x", (*zjxx).zjxx_info.in_station_status);      
    DebugPrintBd("\r\n    ZJXX信息内容-功率状态:%d-%d-%d-%d-%d-%d", (*zjxx).zjxx_info.power_status[0], (*zjxx).zjxx_info.power_status[1],
                          (*zjxx).zjxx_info.power_status[2], (*zjxx).zjxx_info.power_status[3],(*zjxx).zjxx_info.power_status[4], (*zjxx).zjxx_info.power_status[5]);
    DebugPrintBd("\r\n    ZJXX包校验和:0x%02x\r\n", (*zjxx).checksum);
    
    DebugPrintBd("\r\n    ========= ZJXX包-打印结束=========\r\n");
}
 
void print_fkxx(struct fkxx_struct *fkxx)
{
    Tx_monitor_S("\r\n    ========= FKXX包-打印开始=========\r\n");
 
    DebugPrintBd("\r\n    FKXX包总长度:%d", (*fkxx).packet_len);
    DebugPrintBd("\r\n    FKXX包用户地址:0x%02x%02x%02x", (*fkxx).user_addr[0], (*fkxx).user_addr[1], (*fkxx).user_addr[2]);   
    DebugPrintBd("\r\n    FKXX信息内容-反馈标志:0x%02x", (*fkxx).fkxx_info.fk_flag);    
    DebugPrintBd("\r\n    FKXX信息内容-附加信息:0x%02x-0x%02x-0x%02x-0x%02x", (*fkxx).fkxx_info.extra_info[0], (*fkxx).fkxx_info.extra_info[1], (*fkxx).fkxx_info.extra_info[2], (*fkxx).fkxx_info.extra_info[3]);   
    DebugPrintBd("\r\n    FKXX包校验和:0x%02x\r\n", (*fkxx).checksum);
 
    DebugPrintBd("\r\n    ========= FKXX包-打印结束=========\r\n");
 }
 
void read_bd_rx_info(void)
{
    struct txxx_struct txxx;
    struct icxx_struct icxx;
    struct zjxx_struct zjxx;
    struct fkxx_struct fkxx;
 
    if (bd_buf_bitmap & FKXX_BUF) 
    {
        parse_fkxx(&fkxx);
        print_fkxx(&fkxx);
        bd_buf_bitmap &= ~FKXX_BUF;
    }
 
    if (bd_buf_bitmap & ICXX_BUF)
    {
        parse_icxx(&icxx);
        print_icxx(&icxx);
        bd_buf_bitmap &= ~ICXX_BUF;
    }
 
    if (bd_buf_bitmap & ZJXX_BUF)
    {
        parse_zjxx(&zjxx);
        print_zjxx(&zjxx);
        bd_buf_bitmap &= ~ZJXX_BUF;
    }   
 
    if (bd_buf_bitmap & TXXX_BUF)
    {
        parse_txxx(&txxx);
        print_txxx(&txxx);
        bd_buf_bitmap &= ~TXXX_BUF;
    } 
}
 
void copy_packet_from_shared_buf()
{
    if ((bd_shared_rx_buf[1] == 'D') && (bd_shared_rx_buf[2] == 'W')) //收到定位信息$DWXX
       {
           bd_buf_bitmap |= DWXX_BUF;
           //memcpy(dwxx_buf, bd_shared_rx_buf, sizeof(dwxx_buf));
       }
       else if ((bd_shared_rx_buf[1] == 'T') && (bd_shared_rx_buf[2] == 'X')) //收到通信信息$TXXX
       {
           bd_buf_bitmap |= TXXX_BUF;
           memcpy(txxx_buf, bd_shared_rx_buf, sizeof(txxx_buf));
       }
       else if ((bd_shared_rx_buf[1] == 'I') && (bd_shared_rx_buf[2] == 'C')) //收到IC信息$ICXX
       {
           bd_buf_bitmap |= ICXX_BUF;
           memcpy(icxx_buf, bd_shared_rx_buf, sizeof(icxx_buf));
       }
       else if ((bd_shared_rx_buf[1] == 'Z') && (bd_shared_rx_buf[2] == 'J')) //收到自检信息$ZJXX
       {
           bd_buf_bitmap |= ZJXX_BUF;
           memcpy(zjxx_buf, bd_shared_rx_buf, sizeof(zjxx_buf));
       }
       else if ((bd_shared_rx_buf[1] == 'S') && (bd_shared_rx_buf[2] == 'J')) //收到时间信息$SJXX
       {
            bd_buf_bitmap |= SJXX_BUF;
           //memcpy(sjxx_buf, bd_shared_rx_buf, sizeof(sjxx_buf));
       }
       else if ((bd_shared_rx_buf[1] == 'B') && (bd_shared_rx_buf[2] == 'B')) //收到版本信息$BBXX
       {
            bd_buf_bitmap |= BBXX_BUF;
           //memcpy(bbxx_buf, bd_shared_rx_buf, sizeof(bbxx_buf));
       }
       else if ((bd_shared_rx_buf[1] == 'F') && (bd_shared_rx_buf[2] == 'K')) //收到反馈信息$FKXX
       {
           bd_buf_bitmap |= FKXX_BUF;
           memcpy(fkxx_buf, bd_shared_rx_buf, sizeof(fkxx_buf));
       }
}
 
#pragma vector=USCI_A3_VECTOR
__interrupt void USCI_A3_ISR(void)
{
    unsigned int iv_temp;
    
    _DINT();
     PUSHALL
     
     iv_temp = UCA3IV;
     iv_temp = iv_temp % 16;
     if ((iv_temp & 0x02) != 0)
     {      
        bd_rx_char = UCA3RXBUF;
 
        if (bd_rx_char == '$') //开始接收报文
        {
            bd_buf_pointer = 0;
        }
        
        bd_shared_rx_buf[bd_buf_pointer] = bd_rx_char;
 
        if (bd_buf_pointer == 6)//接收到报文中长度字段的第2个字节
        {
            rx_packet_len = bd_shared_rx_buf[5] * 256 + bd_shared_rx_buf[6];
        }
        else if (bd_buf_pointer == (rx_packet_len - 1)) //接收到报文最后一个字节
        {
            copy_packet_from_shared_buf();
        }
 
        if (bd_buf_pointer != (rx_packet_len - 1))
        {
            bd_buf_pointer = (bd_buf_pointer + 1) % RX_BD_MAX_DATA_SIZE; //指针自增
        }
        else
        {
            bd_buf_pointer = 0; //收到最后一个字节后
        }
     }
     
    POPALL
    _EINT();
}
#endif
 
#endif
 
 
#ifndef __APPBD_H__
#define __APPBD_H__
 
#define MAX_PAYLOAD_LEN 210 //即(1680/8)
 
#define INSTRUCTION_SIZE 5
#define PACKET_LEN_SIZE 2
#define USER_ADDR_SIZE 3
#define CHECKSUM_SIZE 1
 
#define IPUC (INSTRUCTION_SIZE + PACKET_LEN_SIZE + USER_ADDR_SIZE + CHECKSUM_SIZE)
 
#define TXSQ_INFO_FIRM_SIZE 7 //即(1 个信息类别 + 3 个用户地址 + 2个电文长度 + 1个应答字节) 
#define TXSQ_FIRM_SIZE (IPUC + TXSQ_INFO_FIRM_SIZE)
 
#define ICJC_INFO_FIRM_SIZE 1 //即帧号，占一个字节
#define ICJC_FIRM_SIZE (IPUC + ICJC_INFO_FIRM_SIZE)
 
#define XTZJ_INFO_FIRM_SIZE 2 //即自检频度，占二个字节
#define XTZJ_FIRM_SIZE (IPUC + XTZJ_INFO_FIRM_SIZE)
 
#define ICXX_INFO_FIRM_SIZE 11 //即(1个帧号+3个通播ID+1个用户特征+2个服务频度+1个通信等级+1个加密标志+2个下属用户总数)
#define ICXX_FIRM_SIZE (IPUC + ICXX_INFO_FIRM_SIZE)
 
#define TXXX_INFO_FIRM_SIZE 9 //即(1个信息类别+3个发信方地址+2个发信时间+2个电文长度+1个CRC标志
#define TXXX_FIRM_SIZE (IPUC + TXXX_INFO_FIRM_SIZE)
#define TXXX_MAX_SIZE (TXXX_FIRM_SIZE + MAX_PAYLOAD_LEN)//TXXX由固定长度和净长度构成
 
#define FKXX_INFO_FIRM_SIZE 5//即(1个反馈标志+4个附加信息)
#define FKXX_FIRM_SIZE (IPUC + FKXX_INFO_FIRM_SIZE)
 
#define ZJXX_INFO_FRIM_SIZE 10 //即(1个IC卡状态+1个硬件状态+1个电池电量+1个入站状态+6个功率状态)
#define ZJXX_FIRM_SIZE (IPUC + ZJXX_INFO_FRIM_SIZE)
 
#define RX_BD_MAX_DATA_SIZE TXXX_MAX_SIZE 
 
#define TXSQ_PAYLOAD_CHINESE 0x44
#define TXSQ_PAYLOAD_BCD 0x46
 
enum {
    DWXX_BUF = (1 << 0),
    TXXX_BUF = (1 << 1),
    ICXX_BUF = (1 << 2),
    ZJXX_BUF = (1 << 3),
    SJXX_BUF = (1 << 4),
    BBXX_BUF = (1 << 5),
    FKXX_BUF = (1 << 6),
};
 
/* =================== RTU到用户机 ============================ */
 
/* 
    注意:因为发送协议中通信申请(txsq)协议有可变数据内容，使用结构体来表示时，因为要通过串口发送出去，
    无法控制长度，所以发送协议不宜采用结构体表示!
struct peri_to_user_struct
{
    struct dwsq_struct dwsq;
    struct txsq_struct txsq;
    struct cksc_struct cksc;
    struct icjc_struct icjc;
    struct xtzj_struct xtzj;
    struct sjsc_struct sjsc;
    struct bbdq_struct bbdq;
};
*/
 
/* =================== 用户机到RTU ============================*/
 
/* 定位信息 */
struct dwxx_struct
{
    unsigned int todo;
};
 
/* 通信信息 */
struct txxx_info_type_struct
{
    unsigned char packet_comm:2;
    unsigned char transfer_format:1;
    unsigned char ack:1;
    unsigned char comm_way:1;
    unsigned char has_key:1;
    unsigned char rest:2;
};
 
struct send_time_struct
{
    unsigned char hour;
    unsigned char minute;
};
 
struct txxx_info_struct
{
    struct txxx_info_type_struct  txxx_info_type;
    unsigned char src_user_addr[3];
    struct send_time_struct send_time;
    unsigned int payload_len;
    unsigned char payload[MAX_PAYLOAD_LEN];
    unsigned char crc;  
};
 
struct txxx_struct 
{
    unsigned char instruction[5];
    unsigned int packet_len; //解析结构体时以整形数据表示其长度
    unsigned char user_addr[3];
    struct txxx_info_struct txxx_info;
    unsigned char checksum;
};
 
struct icxx_info_struct
{
    unsigned char frame_id;
    unsigned char broadcast_id[3];
    unsigned char user_feature;
    unsigned int service_frequency;
    unsigned char comm_level;
    unsigned char encryption_flag;
    unsigned int user_num;
};
 
/* IC信息 */
struct icxx_struct
{
    unsigned char instruction[5];
    unsigned int packet_len;
    unsigned char user_addr[3];
    struct icxx_info_struct icxx_info;
    unsigned char checksum;
};
 
struct zjxx_info_struct
{
    unsigned char ic_status;
    unsigned char hw_status;
    unsigned char battery_quantity;
    unsigned char in_station_status;
    unsigned char power_status[6];
};
 
struct zjxx_struct
{
    unsigned char instruction[5];
    unsigned int packet_len;
    unsigned char user_addr[3];
    struct zjxx_info_struct zjxx_info;
    unsigned char checksum;
};
 
struct sjxx_struct
{
    unsigned int todo;
};
 
struct bbxx_struct
{
    unsigned int todo;
};
 
struct fkxx_info_struct
{
    unsigned char fk_flag;
    unsigned char extra_info[4];
};
 
struct fkxx_struct
{
    unsigned char instruction[5];
    unsigned int packet_len;  
    unsigned char user_addr[3];
    struct fkxx_info_struct fkxx_info;
    unsigned char checksum;
};
 
/*
struct user_to_peri_struct
{
    struct dwxx_struct dwxx;
    struct txxx_struct txxx;
    struct icxx_struct icxx;
    struct zjxx_struct zjxx;
    struct sjxx_struct sjxx;
    struct bbxx_struct bbxx;
    struct fkxx_struct fkxx;
};
*/
 
extern void send_dwsq();
extern void send_txsq(unsigned char cmd, unsigned char *src_user_addr, unsigned char *dst_user_addr, 
                                       unsigned char transfer_format, unsigned char *send_txsq_payload, unsigned int send_txsq_payload_len);
extern void send_cksc();
extern void send_icjc();
extern void send_xtzj();
extern void send_sjsc();
extern void send_bbdq();
 
extern void init_uart3_for_bd();
extern void read_bd_rx_info(void);
 
#endif